﻿///////////////////////////////////////////////////////////////
//                                                           //
// Code from Arcanea Project.                                //
//                                                           //
// Please include this license part to every reproduction    //
//   of code.                                                //
//                                                           //
// This code is under Ms-RL license                          //
//                                                           //
// Please read futher information about the license,         //
//   the project (news and updates) and the                  //
//   contributors on the address :                           //
//     http://www.codeplex.com/Arcanea/                      //
//                                                           //
///////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using Arcanea.NetworkEngine.Abstract.Engines;
using System.Net.Sockets;
using Arcanea.Mediator.Exceptions;
using System.Net;

namespace Arcanea.NetworkEngine.Concrete.Engines.Protocole
{
    /// <summary>
    /// Protocole engine de connection UDP
    /// </summary>
    public class UDPProtocoleEngine : IProtocoleEngine
    {

        private byte[] buffer = new byte[2500];

        public UDPProtocoleEngine(int portReception, int portEnvoie)
        {
            netInformations.PortPrincipal = portReception;
            netInformations.PortSecondaire = portEnvoie;
        }

        public UDPProtocoleEngine(string serveur, int portReception, int portEnvoie)
        {
            netInformations.Server = serveur;
            netInformations.PortPrincipal = portReception;
            netInformations.PortSecondaire = portEnvoie;
        }

        #region Functions non utilisées


        public override bool Connect()
        {
            throw new BadFunctionUseException();
        }

        public override NetInformationContainer AcceptedConnection()
        {
            throw new BadFunctionUseException();
        }

        #endregion

        #region Functions utilisées

        public override bool Bind()
        {
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, netInformations.PortPrincipal);
            netInformations.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            netInformations.Socket.Bind(ipep);
            return true;
        }

        public override bool Send(byte[] array)
        {

            IPEndPoint sender = new IPEndPoint(IPAddress.Parse(netInformations.Server), netInformations.PortSecondaire);
            EndPoint tmpRemote = (EndPoint)(sender);

            if (netInformations.Socket == null) return false;
            try
            {
                netInformations.Socket.SendTo(array, tmpRemote);
            }
            catch (Exception e)
            {
                logger.Error("Unable to send message : " + e.Message);
                return false;
            }
            return true;
        }

        public override byte[] Receive(int taille)
        {
            if (netInformations.Socket == null) return null;

            int readen = 0;
            try
            {
                //EndPoint temp = null;
                readen = netInformations.Socket.Receive/*From*/(buffer, 0, buffer.Length, SocketFlags.None/*, ref temp*/ );
                //netInformations.LastEndPointUsed = temp;
                if (readen != 0)
                {
                    byte[] result = new byte[readen];
                    Array.Copy(buffer, 0, result, 0, readen);
                    return result;
                }
                else
                    return null;
            }
            catch (Exception e)
            {
                logger.Error("Unable to receive message : " + e.Message);
                return null;
            }
        }

        #endregion

        #region Private functions

        #endregion

    }
}
